<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="keywords"
        content="HTML,CSS,HTML5,CSS3,ES6,JavaScript,Vue,Vue.js,TS,TypeScript,webpack,node.js,git,npm,前端,全栈,Web开发" />
    <meta name="description" content="一位Web开发工程师的学习、工作笔记-星之痕。
    内容涵盖：HTML,CSS,HTML5,CSS3,ES6,JavaScript,Vue,Vue.js,TS,TypeScript,前端,全栈,Web开发……等" />
    <title>Vue.js 笔记-星之痕</title>
    <link rel="stylesheet" href="./css/global.css">
</head>

<body>
    <div id="app">

        <div>
            <h2>{{title}}</h2>
            <ul>
                <li v-html="msg" v-for='msg in messages'></li>
            </ul>
        </div>
        <button v-on:click='action'>点击</button>

    </div>

    <script src="js/vue.js"></script>
    <script>
        const nums = [85, 60, 25, 120, 30];
        console.log('初始数组：' + nums);

        // 1. 需求：取出所有小于100的数字
        let newNums = [];
        let total = 0;

        // 普通实现方式
        // for (let n of nums) {
        //     if (n < 100)
        //         newNums.push(n);
        // }

        // 函数实现方式
        newNums = nums.filter(function (n) {
            return n < 100;
        });
        console.log('经过 filter 条件筛选后：' + newNums);
        // console.log('小于100：' + newNums);


        // 2. 需求：将所有小于100的数字*2
        // let new2Nums = [];

        // 普通实现方式
        // for (let n of nums) {
        //     if (n < 100)
        //         new2Nums.push(n * 2);
        // }

        // 函数实现方式1
        // newNums.map(function (n) {
        //     new2Nums.push(n * 2);
        // });

        // 函数实现方式2
        let new2Nums = [];
        new2Nums = newNums.map(n => n * 2);
        console.log('经过 map 函数处理后：' + new2Nums);


        // 3. 需求：将所有小于100*2转化后的数字，再进行相加

        // 普通实现方式
        // for (let n of nums) {
        //     if (n < 100)
        //         total += n*2;
        // }

        // reduce 函数实现方式 1
        // let sum = 0;
        // sum = nums.reduce(function (total, cur) {
        //     console.log('total: ' + total);
        //     console.log('cur: ' + cur);
        //     if (cur >= 100)
        //         cur = 0;
        //     return total + cur * 2;
        // }, 0);

        // reduce 函数实现方式 2
        let sum = 0;
        sum = new2Nums.reduce(function (total, cur) {
            console.log('total: ' + total);
            console.log('cur: ' + cur);
            return total + cur;
        }, 0);
        console.log('经过 reduce 函数实现的结果: ' + sum);


        // 以上3个需求使用高阶函数的实现方式
        let total2 = nums.filter(function (x) {
            return x < 100;
        }).map(function (y) {
            return y * 2;
        }).reduce(function (total, cur) {
            return total + cur;
        }, 0)
        console.log('高阶函数fliter(条件)+map(加工)+reduce(累加)的联合实现: ' + total2);

        // 再来个ES6的终极实现方式
        let total3 = nums.filter(x => x < 100).map(x => x * 2).reduce((x, y) => x + y, 0)

        console.log('高阶函数fliter(条件)+map(加工)+reduce(累加)的终极实现: ' + total3);

        // vue
        const app = new Vue({
            el: '#app',
            data: {
                title: '高阶函数的使用',
                messages: [
                    '编程范式：命令式编程/声明式编程',
                    '面向对象编程（第一公民：对象）/函数式编程（第一公民：函数）',
                    '高阶函数：filter/map/reduce 的使用<br><br>',
                    `filter(): 将一个数组的所有元素经过指定条件筛选后加入新的数组<br>
                    该函数会自动筛选返回结果为true的元素加入到新的数组中<br>
                    *回调函数必需返回一个bool值<br>
                    *返回为true时，会将回调的当前值加入到新的数组中 <br>                  
                    *不会检测空的数组，不会改变原有数组<br><br>
                    array.filter(fn(currentValue,index,arr), thisValue)<br>
                    currentValue 必选，当前元素的值<br>
                    index       可选，当前元素的索引<br>
                    arr         可选，当前元素所属的数组<br>
                    thisValue   可选，对象作为该执行回调时使用，传递给函数，用作 "this" 的值。
                    如果省略了 thisValue ，"this" 的值为 "undefined" <br><br>`,
                    `map(): 创建一个将原数组元素经由函数处理后形成新的数组<br>
                    按照原始数组元素顺序依次处理元素<br>
                     *类似映射：将原数组经过一些特殊需求处理一一映射为新数组<br>
                     *不会检测空的数组，不会改变原有数组<br><br>
                    array.map(fn(currentValue,index,arr), thisValue)<br><br>`,
                    `reduce(): 接收一个函数作为累加器，数组中的每个值（从左到右）开始缩减，最终计算为一个值。<br>
                     按照原始数组元素顺序依次处理元素<br>
                     *对于空数组不会执行回调函数<br>
                     *reduce() 方法不会改变原始数组<br><br>
                     如果设置第二个参数 initialValue，那么 total 初始值=initialValue<br>
                     如果不传第二个参数 initialValue，则函数的第一次执行会将数组中的第一个元素作为 total<br><br>
                     arr.reduce(fn(total,currentValue,currentIndex,sourceArray),initialValue)<br>
                     total               必需。初始值, 或者计算结束后的返回值。<br>
                     currentValue        可选，当前值      <br>
                     currentIndex        可选，当前索引    <br>
                     sourceArray         可选，源数组      <br>
                     initialValue        可选。传递给回调函数的初始值 `,
                ]
            },
            computed: {

            },
            methods: {
                action() {
                    this.title = 'hello!';
                }
            }
        });
    </script>
</body>

</html>